package com.happe.foodeasy.manage.controller.commodity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.happe.foodeasy.manage.commodity.entity.CommodityBaseEntity;
import com.happe.foodeasy.manage.commodity.entity.CommodityTypeEntity;
import com.happe.foodeasy.manage.controller.CommonIdentifyKeyInModelAndView;
import com.happe.foodeasy.manage.dto.*;
import com.happe.foodeasy.manage.common.entity.ManagerEntity;
import com.happe.foodeasy.manage.helper.RetrieveDataHelper;
import com.happe.foodeasy.manage.service.CommodityBaseService;
import com.happe.foodeasy.manage.service.CommodityStatusService;
import com.happe.foodeasy.manage.service.CommodityTypeService;
import com.happe.foodeasy.manage.service.ImagePhotoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.List;

/**
 * 这个类用于对商品信息的存储与访问
 * Created by Administrator on 2016/7/21.
 */
@Controller
@RequestMapping("/commodity")
public class CommodityInfoController {
    private Logger logger = LoggerFactory.getLogger(CommodityInfoController.class);

    private static final String SUCCESS_MESSAGE = "保存成功";
    private static final String DEFEAT_MESSAGE = "保存失败";
    private static final String ALL_COMMODITY_FLAG = "allCommodity";
    private static final String ALL_COMMODITY_TYPE_FLAG = "allCommodityType";
    private static final String RESULT_TYPE_COMMODITY = "allResultTypeCommodity";
    private static final String INDEX_TARGET_SELECT_NAV = "商品管理";
    private static final String COMMODITY_STATUS_LIST = "commodityStatusList";
    private static final String COMMODITY_TYPE_LIST = "commodityTypeList";
    /*进入商品管理界面，需要记录当前被选中的商品的状态与类型，这样才能进行的标记，下面
    * 两个常量就是选中状态与类型的键*/
    private static final String TARGET_COMMODITY_STATUS_ID = "targetCommodityStatusId";
    private static final String TARGET_COMMODITY_TYPE_ID = "targetCommodityTypeId";

    @Resource
    private CommodityBaseService commodityBaseService;
    @Resource
    private ImagePhotoService imagePhotoService;
    @Resource
    private CommodityTypeService commodityTypeService;
    @Resource
    private CommodityStatusService commodityStatusService;
    @Resource
    private RetrieveDataHelper retrieveDataHelper;

    @RequestMapping(value = "/saveBaseInfo.do", method = RequestMethod.POST)
    public ModelAndView saveBaseInfo(MultipartFile photo, CommodityBaseDTO commodityBaseDTO, HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView("commodity/commoditySaveResult");
        String message;
        try {
            long lastCommodityBaseId = commodityBaseService.selectLastLineId();
            initNewCommodityBasePropInfo(commodityBaseDTO, lastCommodityBaseId);
            initInsertInfo(commodityBaseDTO, request.getSession());

            ImagePhotoDTO photoDTO = new ImagePhotoDTO();
            initInsertInfo(photoDTO, request.getSession());
            photoDTO.setCommodityBaseEntityId(lastCommodityBaseId + 1);
            photoDTO.setPhotoOrder(1);
            multipartFile2PhotoDTO(photoDTO, photo);
            commodityBaseService.save(commodityBaseDTO, photoDTO);
            message = SUCCESS_MESSAGE;
        } catch (Exception e) {
            e.printStackTrace();
            message = DEFEAT_MESSAGE;
        }

        modelAndView.addObject("message", message);
        return modelAndView;
    }

    @RequestMapping(value = "/retrieveTargetCommodities.do", method = RequestMethod.GET)
    public ModelAndView retrieveTargetCommodities(long commodityTypeId, long commodityStatusId) {
        ModelAndView modelAndView = new ModelAndView("commodity/indexManage");
        retrieveDataHelper.addAllProvinceInMAV(modelAndView).addAllCommodityTypeInMAV(modelAndView);
        retrieveTargetTypeCommodity(modelAndView, commodityTypeId, commodityStatusId);
        modelAndView.addObject(CommonIdentifyKeyInModelAndView.ALL_NAV_DIRECTORY_KEY, retrieveDataHelper.retrieveAllNavDirectory());
        modelAndView.addObject(CommonIdentifyKeyInModelAndView.TARGET_SELECT_NAV_KEY, INDEX_TARGET_SELECT_NAV);
        modelAndView.addObject(COMMODITY_STATUS_LIST, commodityStatusService.retrieveAllStatus());

        modelAndView.addObject(TARGET_COMMODITY_STATUS_ID, commodityStatusId);
        modelAndView.addObject(TARGET_COMMODITY_TYPE_ID, commodityTypeId);

        addAllCommodityTypes(modelAndView);
        return modelAndView;
    }

    private void addAllCommodityTypes(ModelAndView modelAndView) {
        List<CommodityTypeEntity> result = commodityTypeService.selectAllCommodityType();
        modelAndView.addObject(COMMODITY_TYPE_LIST, result);
    }

    /*这个用法用于查询出商品种类中第一类的所有商品*/
    private void retrieveTargetTypeCommodity(ModelAndView modelAndView, long commodityTypeId, long commodityStatusId) {
        TypeAndStatusDTO typeAndStatusDTO = new TypeAndStatusDTO();
        typeAndStatusDTO.setCommodityStatusId(commodityStatusId);
        typeAndStatusDTO.setCommodityTypeId(commodityTypeId);
        List<CommodityBaseEntity> allFirstTypeCommodity = commodityBaseService.selectAllByTypeAndStatus(typeAndStatusDTO);
        modelAndView.addObject(RESULT_TYPE_COMMODITY, allFirstTypeCommodity);
    }

    /*
    * 在链接图片添加时，链接图片需要与某个商品关联，所以需要显示
    * 所有已上架和未上架的商品的列表，然后供管理员选择某一商品。该controller就是用于获得
    * 所有已上架和未上架的商品，以及商品的类型列表。在关联商品窗口中默认会显示商品第一种类型与状态的商品
    * */
    @RequestMapping(value = "/retrieveAllValidCommodities.do", method = RequestMethod.POST)
//    @ResponseBody
    public void retrieveCommodityForLinkImage(HttpServletResponse response) {
        List<CommodityBaseEntity> allValidCommodity = commodityBaseService.selectFirstTypeAndStatusValidCommodity();
        List<CommodityTypeEntity> allValidCommodityTypeEntity = commodityTypeService.selectAllCommodityType();

        Gson gson = new Gson();
        JsonElement allCommodityJsonEle = gson.toJsonTree(allValidCommodity);
        JsonElement allCommodityTypeEntityJsonEle = gson.toJsonTree(allValidCommodityTypeEntity);

        JsonObject result = new JsonObject();
        result.add(ALL_COMMODITY_FLAG, allCommodityJsonEle);
        result.add(ALL_COMMODITY_TYPE_FLAG, allCommodityTypeEntityJsonEle);

        try {
            response.getWriter().print(gson.toJson(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 该mapping用于获得所有的商品类型
     * <p>
     * 使用HttpServletResponse将所有的商品类型列表返回
     */
    @RequestMapping("/retrieveAllCommodityType")
    public void retrieveAllCommodityType(HttpServletResponse response) {
        List<CommodityTypeEntity> allTypes = commodityTypeService.selectAllCommodityType();
        response.setContentType("application/json; charset=utf-8");
        try {
            OutputStream out = response.getOutputStream();
            JSON.writeJSONString(out, Charset.forName("UTF-8"), allTypes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initNewCommodityBasePropInfo(CommodityBaseDTO commodityBaseDTO, long lastCommodityBaseId) {
        commodityBaseDTO.setId(lastCommodityBaseId + 1);
        commodityBaseDTO.setCommentAmount(0);
        commodityBaseDTO.setCommodityStatus(2);
    }

    private <T extends BaseInsertInfoDTO> void initInsertInfo(T insertBaseDTO, HttpSession session) {
        ManagerEntity currentManager = (ManagerEntity) session.getAttribute("currentManager");
        insertBaseDTO.setInsertManagerId(currentManager.getId());
        insertBaseDTO.setInsertTime(new Date());
        insertBaseDTO.setValidFlag("0");
    }

    private void multipartFile2PhotoDTO(ImagePhotoDTO targetDTO, MultipartFile photo) throws IOException {
        targetDTO.setPhotoName(photo.getOriginalFilename());
        targetDTO.setPhotoByte(photo.getBytes());
    }
}
